package com.zzyl.serve.service.impl;

import java.util.HashMap;
import java.util.List;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huaweicloud.sdk.iotda.v5.IoTDAAsyncClient;
import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.huaweicloud.sdk.iotda.v5.model.ServiceCapability;
import com.huaweicloud.sdk.iotda.v5.model.ShowProductRequest;
import com.huaweicloud.sdk.iotda.v5.model.ShowProductResponse;
import com.zzyl.common.constant.RedisKeyConstant;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.framework.web.service.TokenService;
import com.zzyl.serve.domain.*;
import com.zzyl.serve.dto.DeviceDataDayDto;
import com.zzyl.serve.dto.ElderDto;
import com.zzyl.serve.dto.HealDto;
import com.zzyl.serve.dto.UserLoginRequestDto;
import com.zzyl.serve.mapper.DeviceDataMapper;
import com.zzyl.serve.mapper.FamilyMemberMapper;
import com.zzyl.serve.service.IFamilyMemberService;
import com.zzyl.serve.service.WechatService;
import com.zzyl.serve.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.serve.domain.FamilyMember;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Arrays;
import java.util.Map;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
/**
 * 老人家属Service业务层处理
 *
 * @author itheima
 * @date 2025-03-12
 */
@Service
@Slf4j
public class FamilyMemberServiceImpl extends ServiceImpl<FamilyMemberMapper, FamilyMember> implements IFamilyMemberService {
    @Autowired
    private FamilyMemberMapper familyMemberMapper;

    @Autowired
    private WechatService wechatService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private DeviceDataMapper deviceDataMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IoTDAClient iotClient;

    /**
     * 查询老人家属
     *
     * @param id 老人家属主键
     * @return 老人家属
     */
    @Override
    public FamilyMember selectFamilyMemberById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询老人家属列表
     *
     * @param familyMember 老人家属
     * @return 老人家属
     */
    @Override
    public List<FamilyMember> selectFamilyMemberList(FamilyMember familyMember) {
        return familyMemberMapper.selectFamilyMemberList(familyMember);
    }

    /**
     * 新增老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int insertFamilyMember(FamilyMember familyMember) {
        return save(familyMember) ? 1 : 0;
    }

    /**
     * 修改老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int updateFamilyMember(FamilyMember familyMember) {
        return updateById(familyMember) ? 1 : 0;
    }

    /**
     * 批量删除老人家属
     *
     * @param ids 需要删除的老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除老人家属信息
     *
     * @param id 老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberById(Long id) {
        return removeById(id) ? 1 : 0;
    }


    /**
     * 小程序端 用户登录的逻辑处理
     *
     * @param dto
     * @return
     */
    @Override
    public LoginVo login(UserLoginRequestDto dto) {
        //1.调用微信,查询到openid
        String openid = wechatService.getOpenid(dto.getCode());
        //2.根据openid查询用户
        LambdaQueryWrapper<FamilyMember> familyMemberLambdaQueryWrapper = new LambdaQueryWrapper<>();
        familyMemberLambdaQueryWrapper.eq(FamilyMember::getOpenId, openid);
        FamilyMember familyMember = getOne(familyMemberLambdaQueryWrapper);
        //3.根据Openid判断是否是新用户
        String phone = wechatService.getPhone(dto.getPhoneCode());
        String name = "钢丝球" + RandomUtil.randomNumbers(6);

        if (ObjectUtil.isNotEmpty(familyMember)) {
            //5.新增或者修改用户
            familyMember.setPhone(phone);
            familyMemberMapper.updateById(familyMember);
        } else {
            familyMember = new FamilyMember();
            //4.给用户设置关键字段,openid,手机号,名字
            familyMember.setOpenId(openid);
            familyMember.setPhone(phone);
            familyMember.setName(name);
            save(familyMember);
        }
        //6.生成token并且返回
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", familyMember.getId());
        claims.put("nickName", familyMember.getName());

        String token = tokenService.createToken(claims);
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        loginVo.setNickName(familyMember.getName());
        return loginVo;
    }



    /**
     * 绑定家人
     * @param dto
     */
    @Override
    public void addFamily(ElderDto dto) {
        //根据身份证号查询老人信息
        Elder elder = familyMemberMapper.getElderByIdCard(dto.getIdCard());
        if (ObjectUtil.isEmpty(elder)) {
            throw new RuntimeException("该老人不存在!!!");
        }
        //家属ID
        Long userId = UserThreadLocal.getUserId();
        //老人ID
        Long id = elder.getId();
        //根据家属ID查询中间表
        FamilyMemberElder familyMemberElder =   familyMemberMapper.findFamilyMemberIfRepete(elder.getId());
        //判断该老人是否已经绑定了同一个家属
        if(ObjectUtil.isNotEmpty(familyMemberElder)){
            if(familyMemberElder.getFamilyMemberId().equals(userId)&&familyMemberElder.getElderId().equals(id)){
                throw  new BaseException("该老人已经绑定了同一个家属");
            }
        }
        //将关键数据保存到老人和家属信息的表中
        familyMemberMapper.bindFamily(userId, id,dto.getRemark());
    }

    /**
     * 1.2 查询家人列表
     * 接口地址:/member/user/my
     * 请求方式:GET
     * @return
     */
    @Override
    public List<FamilyVo> findFamily() {
        List<FamilyVo> list = familyMemberMapper.findFamily();
        return list;
    }

    /**
     * 1.3 查看家人列表（分页查询）
     * 接口地址:/member/user/list-by-page
     * 请求方式:GET
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public List<AllFamilyVo> findByPage(Integer pageNum, Integer pageSize) {
        Page page = new Page(pageNum, pageSize);
        List<AllFamilyVo> list = familyMemberMapper.findByPage();
        page.setRecords(list);

        return list;
    }

    @Override
    public List<DeviceDataDayVo> queryDeviceDataListByDay(DeviceDataDayDto dto) {

        LocalDateTime dateTime = LocalDateTimeUtil.of(dto.getStartTime());
        LocalDateTime endTime = dateTime.plusHours(1);
        List<DeviceDataDayVo> list = new ArrayList<>();
        for (int i = 0; i < 24; i++) {
            String[] split = dateTime.toString().split("T");
            String string = split[1];

            String avg = familyMemberMapper.queryDeviceDataListByDay(dateTime, endTime, dto.getIotId(), dto.getFunctionId());
            DeviceDataDayVo deviceDataDayVo = new DeviceDataDayVo();
            if (avg != null) {
                Double v = Double.valueOf(avg);
                //保留一位小数点
                String formattedNumber = String.format("%.1f", v);
                double result = Double.parseDouble(formattedNumber);
                deviceDataDayVo.setDataValue(result);
                deviceDataDayVo.setDateTime(string);
                list.add(deviceDataDayVo);
            }
            if (avg == null) {
                avg = "0";
                deviceDataDayVo.setDataValue(Double.valueOf(avg));
                deviceDataDayVo.setDateTime(string);
                list.add(deviceDataDayVo);
            }
            dateTime = dateTime.plusHours(1);
            endTime = dateTime.plusHours(1);
        }
        return list;
    }

    @Override
    public List<DeviceDataWeekVo> queryDeviceDataListByWeek() {

        Long userId = UserThreadLocal.getUserId();
        List<Elder> elder = familyMemberMapper.queryFamilyMemberElder(userId);
        List<DeviceDataWeekVo> list = new ArrayList<>();
        for (Elder elder1 : elder) {
            String elderName = elder1.getName();
            List<DeviceData> deviceData = familyMemberMapper.queryDeviceDataListByWeek(elderName);

            if (ObjectUtil.isNotEmpty(deviceData)) {
                for (DeviceData data : deviceData) {
                    LocalDateTime alarmTime = data.getAlarmTime();
                    String replace = alarmTime.toString().substring(5, 10).replace("_", "");
                    int datavalue = Integer.parseInt(data.getDataValue());
                    list.add(new DeviceDataWeekVo(replace, datavalue));
                }
            }
        }
        return list;
    }


    @Override
    public OneVo QueryDevicePropertyStatus(HealDto dto) {
        //判断设备是否存在
        Device device = familyMemberMapper.getDeviceById(dto.getProductKey(),dto.getDeviceName());
        if(ObjectUtil.isEmpty(device)){
            throw new BaseException("设备不存在");
        }
        //调用iot拿到设备的属性
        ShowProductRequest request = new ShowProductRequest();
        request.withProductId(dto.getProductKey());
        List<FamilyHealVo> list = new ArrayList<>();
        String str = (String) redisTemplate.opsForHash().get(RedisKeyConstant.IOT_DEVICE_LAST_DATA, device.getIotId());
        List<DeviceData> deviceDataList = JSONUtil.toList(str, DeviceData.class);
        if(ObjectUtil.isEmpty(deviceDataList)){
            throw new BaseException("设备没有数据");
        }
        try {
            ShowProductResponse response = iotClient.showProduct(request);
            List<ServiceCapability> serviceCapabilities = response.getServiceCapabilities();
            serviceCapabilities.forEach(serviceCapability -> {
                serviceCapability.getProperties().forEach(property -> {
                    FamilyHealVo familyHealVo = new FamilyHealVo();
                    //读取redis中的数据
                    deviceDataList.forEach(deviceData1 -> {
                        //确定设备唯一,设置设备数据
                        if(deviceData1.getFunctionId().equals(property.getPropertyName())){
                            familyHealVo.setValue(deviceData1.getDataValue());
                            LocalDateTime localDateTime = LocalDateTimeUtil.of(deviceData1.getAlarmTime());
                            ZoneId zoneId = ZoneId.systemDefault();
                            long timestampMillis = localDateTime.atZone(zoneId).toInstant().toEpochMilli();
                            familyHealVo.setTime(timestampMillis);
                        }
                    });
                    //封装数据
                    familyHealVo.setUnit(property.getUnit());
                    familyHealVo.setName(property.getDescription());
                    familyHealVo.setIdentifier(property.getPropertyName());
                    familyHealVo.setDataType(property.getDataType());
                    list.add(familyHealVo);
                });
            });
        }catch (Exception e)
        {
            throw new BaseException("调用IOT平台查询详情失败，请重试");
        }
        TwoVo twoVo = new TwoVo(list);
        OneVo oneVo = new OneVo(twoVo);
        return oneVo;
    }
}